/*
 * IdeogramBrowser/ideogram/IdeogramMainWindow.java
 * 
 * Created on 09.06.2004
 * 
 */
package visiopuce.ideogram;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.awt.print.PageFormat;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Vector;
import java.util.zip.GZIPInputStream;

import javax.imageio.ImageIO;
import javax.swing.ButtonGroup;
import javax.swing.JApplet;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.junit.Assert;

import visiopuce.ideogram.db.IdeogramDB;
import visiopuce.ideogram.input.CommonFileFilter;
import visiopuce.ideogram.input.CopyNumberMerger;
import visiopuce.ideogram.input.DataSlot;
import visiopuce.ideogram.input.FileVersion;
import visiopuce.ideogram.input.ParamTextReaderModel;
import visiopuce.ideogram.util.MathUtility;

//import com.sun.image.codec.jpeg.JPEGCodec;
//import com.sun.image.codec.jpeg.JPEGEncodeParam;
//import com.sun.image.codec.jpeg.JPEGImageEncoder;

/**
 * Shows ideograms of all 24 chromosoms.
 * 
 * @author muellera
 */
public class IdeogramMainWindow extends JApplet implements ActionListener,
		ChangeListener {
	private static final long serialVersionUID = 1L;
	private static final int APP_WIDTH = 900;
	private static final int APP_HEIGHT = 1300;

	public static final int NUM_OF_CHROMOSOMES = 24;
	public static String titre = "";

	public static String causal;

	private IdeogramDB db;
	// protected GeneDB gene_db;
	private IdeogramView[] ideograms;

	// Window
	protected JTextPane infoPanel;
	protected JScrollPane scroller;
	private JPanel chr_panel;

	private JTabbedPane tabs;

	// MENUS
	private ButtonGroup zoomButtons;
	// private boolean dependentWindow;

	private Vector<DataSlot> slots;

	public AllParameters parameters;
	private PageFormat pageFormat;

	// serveral often instantiated variables made global
	private IColorMapper mapper;
	private TableColorMapper map;
	private MarkerCollection[] mc;
	private CopyNumberMerger merger;
	JPopupMenu popmenu;
	String numeroPatient = "";

	public void init() {

		causal = getParameter("causal");
		numeroPatient = getParameter("numeroPatient");
		String segmentation = getParameter("segmentation");
//		 numeroPatient = "S08-0288";
//		 causal =
//		 "17::41006823::41647903::S08-0101::RM-SPM::1::http://localhost/webroot/browser.php?id=5&idAlteration=948&idPuce=26;;11::67998126::68744672::S08-0269::Autisme, retard psychomoteur et langage::1::http://localhost/webroot/browser.php?id=5&idAlteration=2656&idPuce=116;;11::68852465::69125296::S08-0269::Autisme, retard psychomoteur et langage::1::http://localhost/webroot/browser.php?id=5&idAlteration=2657&idPuce=116;;11::69673725::69906819::S08-0269::Autisme, retard psychomoteur et langage::1::http://localhost/webroot/browser.php?id=5&idAlteration=2658&idPuce=116;;11::70138399::70268977::S08-0269::Autisme, retard psychomoteur et langage::1::http://localhost/webroot/browser.php?id=5&idAlteration=2659&idPuce=116;;11::70671199::71012019::S08-0269::Autisme, retard psychomoteur et langage::1::http://localhost/webroot/browser.php?id=5&idAlteration=2660&idPuce=116;;11::71252826::71557939::S08-0269::Autisme, retard psychomoteur et langage::1::http://localhost/webroot/browser.php?id=5&idAlteration=2661&idPuce=116;;11::71675131::72813662::S08-0269::Autisme, retard psychomoteur et langage::1::http://localhost/webroot/browser.php?id=5&idAlteration=2662&idPuce=116;;9::14082175::14366038::S08-0630::Retard global des acquisitions associé à des anomalies morphologiques, une scloliose::1::http://localhost/webroot/browser.php?id=5&idAlteration=4712&idPuce=174;;";
//		 String segmentation = "10-100-100";

		pageFormat = PrinterJob.getPrinterJob().defaultPage();

		slots = new Vector<DataSlot>();

		// data base
		db = new IdeogramDB();
		// gene_db = new GeneDB();

		JPanel p = new JPanel();
		p.setLayout(new BorderLayout());
		p.setBackground(Color.white);
		if (numeroPatient != null) {
			titre = "Patient numéro : " + numeroPatient
					+ "        Parametres de segmentation : " + segmentation;
			JLabel titreLabel = new JLabel(titre);
			p.add(titreLabel, BorderLayout.NORTH);
		}

		// add one panel per chromosome
		chr_panel = new JPanel();
		chr_panel.setBackground(Color.white);
		chr_panel.setOpaque(true);
		chr_panel.setLayout(new GridBagLayout());

		GridBagConstraints c = new GridBagConstraints();
		c.anchor = GridBagConstraints.NORTHWEST;
		c.gridheight = 1;
		c.gridwidth = 1;
		c.fill = GridBagConstraints.NONE;

		// load options or build new optionset
		parameters = new AllParameters();

		ideograms = new IdeogramView[NUM_OF_CHROMOSOMES];
		int n2 = ideograms.length / 2;
		for (int i = 0; i < ideograms.length; ++i) {
			ideograms[i] = new IdeogramView();
			ideograms[i].setDataModel(slots);
			ideograms[i].setChromosome(i + 1);
			ideograms[i].setIdeogramDB(db);
			// ideograms[i].setGeneDB(gene_db);
			ideograms[i].setMainWindow(this);
			ideograms[i].addSelectionChangedListener(this);

			c.gridx = i % n2;
			c.gridy = i / n2;
			chr_panel.add(ideograms[i], c);
		}
		p.add(chr_panel, BorderLayout.CENTER);
		// setup scroller
		scroller = new JScrollPane(p, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
				JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
		scroller.setFocusable(false);

		// disable all key strokes
		scroller.setInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
				null);

		// setup info panel
		infoPanel = new JTextPane();
		infoPanel.setContentType("text/html");
		infoPanel.setEditable(false);
		infoPanel.setEnabled(true);

		// set up ScrollPanes
		JScrollPane infoScroller = new JScrollPane(infoPanel);
		infoScroller.setAlignmentY(Component.TOP_ALIGNMENT);

		// setup tabbed pane
		tabs = new JTabbedPane();
		tabs.addTab("Info", infoScroller);
		tabs.setAlignmentY(Component.TOP_ALIGNMENT);

		// setup splitter
		// splitter = new JSplitPane(JSplitPane.VERTICAL_SPLIT, scroller,
		// boxer);
		getContentPane().add(scroller);

		// setup popup menu
		popmenu = new JPopupMenu();
		JMenuItem menuitem = new JMenuItem("Zoom +");
		menuitem.addActionListener(this);
		popmenu.add(menuitem);
		menuitem = new JMenuItem("Zoom -");
		menuitem.addActionListener(this);
		popmenu.add(menuitem);
		menuitem = new JMenuItem("Chromosome entier");
		menuitem.addActionListener(this);
		popmenu.add(menuitem);

		popmenu.addSeparator();
		popmenu.add(createViewMenu());

		// save
		menuitem = new JMenuItem("Enregistrer", 'S');
		menuitem.addActionListener(this);
		popmenu.add(menuitem);
		
		// save
		menuitem = new JMenuItem("Enregistrer le caryotype pour le rapport");
		menuitem.addActionListener(this);
		popmenu.add(menuitem);
		
		menuitem = new JMenuItem("Imprimer un chromosome");
		menuitem.addActionListener(this);
		popmenu.add(menuitem);

		menuitem = new JMenuItem("Imprimer tous les chromosomes");
		menuitem.addActionListener(this);
		popmenu.add(menuitem);

		setOptimumSize();
		boolean success = true;

		success &= loadIdeogramDatabase();

		if (success) {
			importParam();
		}

		setSize(APP_WIDTH, APP_HEIGHT);

	}

	private JMenu createViewMenu() {

		// Zoom Menu
		JMenu sub = new JMenu("Zoom");
		zoomButtons = new ButtonGroup();
		JRadioButtonMenuItem but;

		but = new JRadioButtonMenuItem("50%");
		but.setActionCommand("zoom:50");
		but.addActionListener(this);
		zoomButtons.add(but);
		sub.add(but);

		but = new JRadioButtonMenuItem("75%");
		but.setActionCommand("zoom:75");
		but.addActionListener(this);
		zoomButtons.add(but);
		sub.add(but);

		but = new JRadioButtonMenuItem("80%");
		but.setActionCommand("zoom:80");
		but.addActionListener(this);
		zoomButtons.add(but);
		sub.add(but);

		but = new JRadioButtonMenuItem("100%");
		but.setActionCommand("zoom:100");
		but.addActionListener(this);
		zoomButtons.add(but);
		sub.add(but);
		zoomButtons.setSelected(but.getModel(), true);

		but = new JRadioButtonMenuItem("150%");
		but.setActionCommand("zoom:150");
		but.addActionListener(this);
		zoomButtons.add(but);
		sub.add(but);

		but = new JRadioButtonMenuItem("200%");
		but.setActionCommand("zoom:200");
		but.addActionListener(this);
		zoomButtons.add(but);
		sub.add(but);

		but = new JRadioButtonMenuItem("300%");
		but.setActionCommand("zoom:300");
		but.addActionListener(this);
		zoomButtons.add(but);
		sub.add(but);

		return sub;
	}

	public void showErrorDialog(String message) {
		JOptionPane.showMessageDialog(this, message, "Error",
				JOptionPane.ERROR_MESSAGE);
	}

	public void showInfoDialog(String message) {
		JOptionPane.showMessageDialog(this, message, "Information",
				JOptionPane.INFORMATION_MESSAGE);
	}

	public void actionPerformed(ActionEvent event) {
		if (!isVisible())
			return;

		String cmd = event.getActionCommand();

		if (cmd.equalsIgnoreCase("Enregistrer")) {
			actionFileSave();
			return;
		}
		
		if (cmd.equalsIgnoreCase("Enregistrer le caryotype pour le rapport")) {
			actionSaveImage();
			return;
		}

		if (cmd.equalsIgnoreCase("Imprimer un chromosome")) {
			actionFilePrintSingle();
			return;
		}

		if (cmd.equalsIgnoreCase("Imprimer tous les chromosomes")) {
			actionFilePrintAll();
			return;
		}

		if (cmd.startsWith("zoom:")) { // zoom command
			int zoom = Integer.parseInt(cmd.substring(5));
			if (zoom > 0) {
				setZoom(zoom);
			}
			return;
		}

		// from popupmenu
		if (cmd.equalsIgnoreCase("zoom +")) {
			((IdeogramView) ((JPopupMenu) ((JMenuItem) event.getSource())
					.getParent()).getInvoker()).zoom(-1);
			return;
		}

		if (cmd.equalsIgnoreCase("zoom -")) {
			((IdeogramView) ((JPopupMenu) ((JMenuItem) event.getSource())
					.getParent()).getInvoker()).zoom(1);
			return;
		}

		if (cmd.equalsIgnoreCase("Chromosome entier")) {
			((IdeogramView) ((JPopupMenu) ((JMenuItem) event.getSource())
					.getParent()).getInvoker()).resetView();
			return;
		}

	}

	/**
	 * Updates all marker collections
	 * 
	 */
	private void update() {
		waitCursor();
		try {
			collectGarbage();
			rebuildMarkerCollection();
			// updateInfoPanels(ideograms[currentChromosome]);
		} finally {
			normalCursor();
		}
	}

	private void rebuildMarkerCollection() {
		if (parameters.fieldA == AllParameters.FieldA.LOH
				&& parameters.versionLoaded == FileVersion.V1_0
				|| (parameters.fieldB == AllParameters.FieldB.LOHPROB)
				&& parameters.versionLoaded != FileVersion.V1_0) { // choose a
			// different
			// color
			// scheme
			// for the
			// LOH mode
			map = new TableColorMapper();

			map.getColorTable().add(new Color(0.5f, 0.5f, 1.0f));
			map.getColorTable().add(Color.BLUE);
			map.getColorTable().add(Color.MAGENTA);
			mapper = map;
		} else {
			mapper = new DefaultColorMapper();
		}

		clearMarkers();

		for (int j = 0; j < slots.size(); ++j) {
			// mc=null;
			mc = slots.get(j).convertToMarkerCollection(mapper);

			Assert.assertNotNull(mc);
			Assert.assertEquals(mc.length, ideograms.length); // one collection
			// per
			// chromosome
			for (int i = 0; i < mc.length; ++i) {
				ideograms[i].setDataModel(slots);
				Assert.assertNotNull(mc[i]);
				ideograms[i].addMarkers(mc[i]);
			}
		}

		// consensus region
		if (parameters.consensus_mode) {
			merger = new CopyNumberMerger();
			merger.setDifferenceMode(true);
			int threshold = MathUtility.restrict(
					parameters.consensus_threshold, 1, slots.size());
			merger.setThreshold(threshold);
			parameters.consensus_threshold = threshold;

			for (DataSlot slot : slots) {
				merger.add(slot);
			}

			mc = merger.convertToMarkerCollection(mapper);

			Assert.assertNotNull(mc);
			Assert.assertEquals(mc.length, ideograms.length); // one collection
			// per
			// chromosome
			LinkedList<String> l = new LinkedList<String>();
			l.add("Consensus Region");
			for (int i = 0; i < mc.length; ++i) {
				Assert.assertNotNull(mc[i]);
				mc[i].setName(l);
				mc[i].setColor(Color.MAGENTA);

				ideograms[i].addMarkers(mc[i]);
				ideograms[i].setConsensusMode(true);
			}

		} else {
			for (int i = 0; i < ideograms.length; ++i) {
				ideograms[i].setConsensusMode(false);
			}
		}
		validate();
	}

	private void setZoom(int zoom) {
		if (zoom < 20)
			zoom = 20;
		if (zoom > 500)
			zoom = 500;

		double z = (double) zoom / 100;

		for (int i = 0; i < ideograms.length; ++i) {
			ideograms[i].setZoomFactor(z, z);
		}
		validate();
	}

	/**
	 * Sets the current mouse cursor to a normal cursor.
	 * 
	 */
	protected void normalCursor() {
		Cursor normalCursor = new Cursor(Cursor.DEFAULT_CURSOR);
		setCursor(normalCursor);
	}

	/**
	 * Sets the current mouse cursor to a waiting cursor (e.g. hourglass).
	 * {@see #normalCursor()}
	 */
	protected void waitCursor() {
		Cursor hourglassCursor = new Cursor(Cursor.WAIT_CURSOR);
		setCursor(hourglassCursor);
	}

//	/*
//	 * http://itextdocs.lowagie.com/tutorial/
//	 */
//	public void writePDFFile(OutputStream os) throws DocumentException {
//
//		// step 1: creation of a document-object
//		com.lowagie.text.Document document = new com.lowagie.text.Document();
//
//		// step 2: creation of the writer
//		PdfWriter writer = PdfWriter.getInstance(document, os);
//
//		// step 3: we open the document
//		document.open();
//
//		// step 4: we grab the ContentByte and do some stuff with it
//
//		// we create a fontMapper and read all the fonts in the font directory
//		DefaultFontMapper mapper = new DefaultFontMapper();
//		FontFactory.registerDirectories();
//		// mapper.insertDirectory("c:\\windows\\fonts");
//
//		PdfContentByte cb = writer.getDirectContent();
//
//		IdeogramViewPrintingHelper helper = new IdeogramViewPrintingHelper(
//				ideograms);
//
//		Dimension dim = helper.getDim();
//
//		PdfTemplate tp = cb.createTemplate(dim.width, dim.height);
//		Graphics2D g2 = tp.createGraphics(dim.width, dim.height, mapper);
//		Rectangle r = document.getPageSize();
//
//		double scale = Math.min(r.width() / dim.width, r.height() / dim.height);
//		g2.scale(scale, scale);
//		helper.directPaintAll(g2);
//		g2.dispose();
//		cb.addTemplate(tp, 0, 0);
//
//		document.close();
//	}

	protected void actionFileSave() {
		JFileChooser dialog = new JFileChooser();
		CommonFileFilter filter;

		dialog.setAcceptAllFileFilterUsed(false);
		filter = new CommonFileFilter("JPEG Image (.jpg,.jpeg)");
		filter.addExtension("jpg");
		filter.addExtension("jpeg");
		dialog.addChoosableFileFilter(filter);

//		filter = new CommonFileFilter("Portable Document Format (.pdf)");
//		filter.addExtension("pdf");
//		dialog.addChoosableFileFilter(filter);

		if (dialog.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
			File file = dialog.getSelectedFile();

			String ext = new String();
			if (file.getName().lastIndexOf(".") == -1) {
				int idx = -1;
				for (int i = 0; idx < dialog.getChoosableFileFilters().length; ++i) {
					if (dialog.getChoosableFileFilters()[i] == dialog
							.getFileFilter()) {
						idx = i;
						break;
					}
				}
				switch (idx) {
				case 0:
					ext = "jpg";
					break;
//				case 1:
//					ext = "pdf";
//					break;

				default:
					ext = "jpg";
				}
				file = new File(file.getAbsolutePath() + "." + ext);
			}

			if (file.exists()) {
				// overwrite file??
				int res = JOptionPane
						.showConfirmDialog(
								this,
								"Le fichier '"
										+ file.getName().toString()
										+ "'existe déjà! Voulez-vous remplacer le fichier existant?");
				if (res != JOptionPane.OK_OPTION)
					return;
			}

			// open output stream
			FileOutputStream os;
			String path = file.getAbsolutePath();
			try {
				os = new FileOutputStream(path);
			} catch (FileNotFoundException e) {
				JOptionPane.showMessageDialog(this,
						"Impossible d'ouvrir le fichier\r\n" + path, "Error",
						JOptionPane.ERROR_MESSAGE);
				return;
			}
			if (os == null) {
				JOptionPane.showMessageDialog(this,
						"Impossible d'ouvrir le fichier\r\n" + path, "Error",
						JOptionPane.ERROR_MESSAGE);
				return;
			}

			if (ext.compareToIgnoreCase("jpg") == 0
					|| ext.compareToIgnoreCase("jpeg") == 0) {
				// jpeg output
				IdeogramViewPrintingHelper helper = new IdeogramViewPrintingHelper(
						ideograms);

				Dimension dim = helper.getDim();
				BufferedImage image = new BufferedImage(dim.width, dim.height,
						BufferedImage.TYPE_INT_RGB);

				Graphics g = image.createGraphics();
				g.setColor(Color.WHITE);
				g.fillRect(0, 0, image.getWidth(), image.getHeight());
				helper.directPaintAll(g);
				g.dispose();

				try {
					
					 ImageIO.write(image, "jpeg", os);
					
//					JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os);
//					JPEGEncodeParam param = encoder
//							.getDefaultJPEGEncodeParam(image);
//					param.setQuality(1.0f, false);
//					encoder.setJPEGEncodeParam(param);
//					encoder.encode(image);
					os.close();
				} catch (IOException e) {
					JOptionPane.showConfirmDialog(this,
							"Erreur lors de l'écriture du fichier\r\n" + path);
					return;
				}
				return;
			}

//			if (ext.compareToIgnoreCase("pdf") == 0) {
//
//				try {
//					writePDFFile(os);
//				} catch (DocumentException e) {
//					e.printStackTrace();
//					showErrorDialog("Erreur pendant la création du fichier PDF\n"
//							+ path + "\n" + e.getMessage());
//				} catch (Exception e) {
//					e.printStackTrace();
//					showErrorDialog("Erreur pendant la création du fichier PDF\n"
//							+ path + "\n" + e.getMessage());
//				}
//
//				try {
//					os.close();
//				} catch (IOException e) {
//					e.printStackTrace();
//					showErrorDialog("I/O Erreur pendant la fermeture du fichier\n"
//							+ path + "\n" + e.getMessage());
//				}
//			}
		}
	}

	protected void actionSaveImage() {
		JFileChooser dialog = new JFileChooser();
		CommonFileFilter filter;

		dialog.setAcceptAllFileFilterUsed(false);
		dialog.setSelectedFile(new File("caryo_"+numeroPatient));

		filter = new CommonFileFilter("JPEG Image (.jpg,.jpeg)");
		filter.addExtension("jpg");
		filter.addExtension("jpeg");
		dialog.addChoosableFileFilter(filter);


		if (dialog.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
			File file = dialog.getSelectedFile();

			String ext = new String();
			if (file.getName().lastIndexOf(".") == -1) {
				int idx = -1;
				for (int i = 0; idx < dialog.getChoosableFileFilters().length; ++i) {
					if (dialog.getChoosableFileFilters()[i] == dialog
							.getFileFilter()) {
						idx = i;
						break;
					}
				}
				switch (idx) {
				case 0:
					ext = "jpg";
					break;

				default:
					ext = "jpg";
				}
				file = new File(file.getAbsolutePath() + "." + ext);
			}

			if (file.exists()) {
				// overwrite file??
				int res = JOptionPane
						.showConfirmDialog(
								this,
								"Le fichier '"
										+ file.getName().toString()
										+ "'existe déjà! Voulez-vous remplacer le fichier existant?");
				if (res != JOptionPane.OK_OPTION)
					return;
			}

			// open output stream
			FileOutputStream os;
			String path = file.getAbsolutePath();
			try {
				os = new FileOutputStream(path);
			} catch (FileNotFoundException e) {
				JOptionPane.showMessageDialog(this,
						"Impossible d'ouvrir le fichier\r\n" + path, "Error",
						JOptionPane.ERROR_MESSAGE);
				return;
			}
			if (os == null) {
				JOptionPane.showMessageDialog(this,
						"Impossible d'ouvrir le fichier\r\n" + path, "Error",
						JOptionPane.ERROR_MESSAGE);
				return;
			}

			if (ext.compareToIgnoreCase("jpg") == 0
					|| ext.compareToIgnoreCase("jpeg") == 0) {
				// jpeg output
				IdeogramViewPrintingHelper helper = new IdeogramViewPrintingHelper(
						ideograms);

				Dimension dim = helper.getDim();
				BufferedImage image = new BufferedImage(dim.width, dim.height,
						BufferedImage.TYPE_INT_RGB);

				Graphics g = image.createGraphics();
				g.setColor(Color.WHITE);
				g.fillRect(0, 0, image.getWidth(), image.getHeight());
				helper.directPaintAll(g);
				g.dispose();

				try {
					 ImageIO.write(image, "jpeg", os);
//					JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os);
//					JPEGEncodeParam param = encoder
//							.getDefaultJPEGEncodeParam(image);
//					param.setQuality(1.0f, false);
//					encoder.setJPEGEncodeParam(param);
//					encoder.encode(image);
					os.close();
				} catch (IOException e) {
					JOptionPane.showConfirmDialog(this,
							"Erreur lors de l'écriture du fichier\r\n" + path);
					return;
				}
				return;
			}

		}
	}

	protected void actionFilePrintSingle() {
		IdeogramView view = getSelectedView();
		if (view == null) {
			showInfoDialog("Un chromosome doit être selectionné!");
			return;
		}

		PrinterJob job = PrinterJob.getPrinterJob();
		if (job.printDialog()) {
			job.setPrintable(view, pageFormat);
			try {
				job.print();
			} catch (PrinterException e) {
				showErrorDialog("Erreur d'impression :\n" + e.getMessage());
			}
		}
	}

	protected void actionFilePrintAll() {
		PrinterJob job = PrinterJob.getPrinterJob();
		if (job.printDialog()) {
			job.setPrintable(new IdeogramViewPrintingHelper(ideograms),
					pageFormat);
			try {
				job.print();
			} catch (PrinterException e) {
				showErrorDialog("Erreur d'impression :\n" + e.getMessage());
			}
		}
	}

	public IdeogramView getSelectedView() {
		for (int i = 0; i < ideograms.length; ++i)
			if (ideograms[i].isActive())
				return ideograms[i];
		return null;
	}

	public IdeogramDB getIdeogramDB() {
		return db;
	}

	/**
	 * Removes all markers from the all chromosomes.
	 * 
	 */
	public void clearMarkers() {
		for (int i = 0; i < ideograms.length; ++i) {
			ideograms[i].clearMarkers();
		}
	}

	private void collectGarbage() {
		// collect garbage
		Runtime.getRuntime().gc();
	}

	/**
	 * Loads the ideogram database from the jar archive (folder
	 * data/ideogram.csv).
	 * 
	 * @param notifier
	 * 
	 * @return True on success.
	 */
	public boolean loadIdeogramDatabase() {
		try {
			InputStream stream;
			String name;

			name = "data/ideogram";
			stream = getClass().getResourceAsStream(name);
			if (stream == null) {
				name = "data/ideogram.gz";
				stream = getClass().getResourceAsStream(name);
				if (stream != null) {
					stream = new GZIPInputStream(stream);
				}
			}

			if (stream == null) {

				return false;
			}

			if (!getIdeogramDB().read(new InputStreamReader(stream)))
				return false;
		} catch (Exception e) {

		}
		return true;
	}

	public void setOptimumSize() {
		double v = Double.NaN;
	}

	/**
	 * If a selection changed in one of the ideograms
	 */
	public void stateChanged(ChangeEvent e) {
		if (e.getSource() instanceof IdeogramView) {
			IdeogramView ideo = (IdeogramView) e.getSource();
			// updateInfoPanels(ideo);

			// set all other ideograms to be not active
			for (int i = 0; i < ideograms.length; ++i) {
				ideograms[i].setActive(ideograms[i] == ideo);
			}
			return;
		}
	}

	public boolean importParam() {
		try {
			ParamTextReaderModel model = new ParamTextReaderModel();
			model.load();

			DataSlot s = new DataSlot(parameters);
			s.addModel(model);
			slots.add(s);
		} catch (IOException e) {

			showErrorDialog("I/O error while importing");
			return false;
		} catch (Exception e) {
			e.printStackTrace();

			showErrorDialog("Exception while importing ");
			return false;
		} finally {
			normalCursor();
		}

		update();
		repaint();
		return true;
	}

}
